/*******************************************************************************
 * Copyright (c) 2007 University of Oslo.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     University of Oslo - initial API and implementation
 *******************************************************************************/

package com.cea.papyrus.diagram.sequence.sedi.edit.manager;


import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.tools.CellEditorLocator;
import org.eclipse.gef.tools.DirectEditManager;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import org.eclipse.uml2.uml.NamedElement;

import com.cea.papyrus.diagram.sequence.sedi.model.util.ModelUtil;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;

/**
 * Edit manager that coordinates direct editing of NamedElements.
 * 
 * @author frankd@ifi.uio.no
 */
public class LabelDirectEditManager extends DirectEditManager {

    public LabelDirectEditManager(GraphicalEditPart source, CellEditorLocator locator) {
        super(source, null, locator);
    }

    @Override
    protected CellEditor createCellEditorOn(Composite composite) {
        // Text fields have this problem that when characters are added so
        // that the full text exceeds the visible area of the editor, the
        // control scrolls in order to show the caret. When the control is
        // subsequently resized so as to be able to display the entire text,
        // the control does not automatically scroll the text back.
        //
        // See also Text#setBounds(x,y,w,h,flags) for a comment
        //
        // We adopt the same solution, which is to save the selection,
        // go to the beginning of the text, then reset the initial selection.
        final TextCellEditor editor = new TextCellEditor(composite, getEditorStyle());
        editor.getControl().addControlListener(new ControlListener() {
            public void controlMoved(ControlEvent e) {
            }

            public void controlResized(ControlEvent e) {
                Text c = (Text) e.getSource();
                Point p = c.getSelection();
                c.setSelection(0);
                c.setSelection(p);
            }
        });
        return editor;
    }

    /**
     * Selects the SWT style to be applied to the cellEditor. Subclasses may override.
     * 
     * @return the style to be applied to the cellEditor.
     */
    protected int getEditorStyle() {
        return SWT.SINGLE /* SWT.MULTI | SWT.WRAP */;
    }

    @Override
    protected void initCellEditor() {
        getCellEditor().setValue(getInitialEditorText());
        Text text = (Text) getCellEditor().getControl();
        text.selectAll();
    }

    /**
     * Subclasses should override this method to return the inital text of the editor.
     * 
     * @return the text to show in the editor when it opens.
     */
    @SuppressWarnings("unchecked")
    protected String getInitialEditorText() {
        NamedElement named;
        Object model = getEditPart().getModel();
        if (model instanceof GraphElement)
            named = ModelUtil.<NamedElement> getSemantic((GraphElement) model);
        else
            named = (NamedElement) model;
        return named.getName();
    }
}
